#!/bin/sh
# Copyright (c) Nuvoton Technology Corp. All rights reserved.
# Description:	WiFi connection setup script for RTL USB devices
# Version:	2013-09-05	first release version, support RTL8188/RTL8188AP
#		2013-11-08	support SSID naming with space character
#		2013-11-18	remove router and DNS setting in dnsmasq.conf
#		2014-05-06	support RTL8189/RTL8189AP
#		2014-07-11	support RTL8821/RTL8821AP
#		2014-07-29	confirm has connected to AP before setting IP
#		2015-01-19	support bridge mode
# Author:	C.C. Chang	ccchang12@nuvoton.com.tw
WIFI_PATH=/mnt/nand1-1/wifi
NETCONFIG_FILE=$WIFI_PATH/network_config
# set ENABLE to YES/NO
STA_ENABLE=`awk '{if ($1=="STA_ENABLE") {print $2}}' $NETCONFIG_FILE`
# set WiFi Chipset to RTL8188/RTL8189/RTL8821
STA_CHIPSET=`awk '{if ($1=="STA_CHIPSET") {print $2}}' $NETCONFIG_FILE`
# set BOOTPROTO to DHCP/STATIC
STA_BOOTPROTO=`awk '{if ($1=="STA_BOOTPROTO") {print $2}}' $NETCONFIG_FILE`
# set IP address, only usful to STATIC IP
STA_IPADDR=`awk '{if ($1=="STA_IPADDR") {print $2}}' $NETCONFIG_FILE`
# set GATEWAY address, only usful to STATIC IP, a space means does not set it
STA_GATEWAY=`awk 'BEGIN { FS=" |" } {if ($1=="STA_GATEWAY") {print $2}}' $NETCONFIG_FILE`
# set NETWORK_TYPE to Infra/Adhoc, only Infra is supported now
STA_NETWORK_TYPE=`awk '{if ($1=="STA_NETWORK_TYPE") {print $2}}' $NETCONFIG_FILE`
# set Wireless AP's SSID
STA_SSID=`awk '{if ($1=="STA_SSID") { print $2 }}' $NETCONFIG_FILE`
if [ "$(echo "$STA_SSID" | cut -c1)" = '"' ]; then
	STA_SSID=`awk -F\" '{if ($1=="STA_SSID ") { print $2 }}' $NETCONFIG_FILE`
fi
# set STA_AUTH_MODE to OPEN/SHARED/WPAPSK/WPA2PSK/WPSPBC/WPSPIN/WPSREG
STA_AUTH_MODE=`awk '{if ($1=="STA_AUTH_MODE") {print $2}}' $NETCONFIG_FILE`
# set ENCRYPT_TYPE to NONE/WEP/TKIP/AES
STA_ENCRYPT_TYPE=`awk '{if ($1=="STA_ENCRYPT_TYPE") {print $2}}' $NETCONFIG_FILE`
# set authentication key to be either
# WEP-HEX example: 4142434445
# WEP-ASCII example: "ABCDE"
# TKIP/AES-ASCII: 8~63 ASCII
STA_AUTH_KEY=`awk '{if ($1=="STA_AUTH_KEY") {print $2}}' $NETCONFIG_FILE`

AP_ENABLE=`awk '{if ($1=="AP_ENABLE") {print $2}}' $NETCONFIG_FILE`
AP_CHIPSET=`awk '{if ($1=="AP_CHIPSET") {print $2}}' $NETCONFIG_FILE`
AP_IPADDR=`awk '{if ($1=="AP_IPADDR") {print $2}}' $NETCONFIG_FILE`
# set AP_GATEWAY address, a space means does not set it
#AP_GATEWAY=`awk 'BEGIN { FS=" |#" } {if ($1=="AP_GATEWAY") {print $2}}' $NETCONFIG_FILE`
AP_SSID=`awk 'BEGIN { FS=" |" } {if ($1=="AP_SSID") {print $2}}' $NETCONFIG_FILE`
if [ "$(echo "$AP_SSID" | cut -c1)" = '"' ]; then
	AP_SSID=`awk -F\" '{if ($1=="AP_SSID ") { print $2 }}' $NETCONFIG_FILE`
fi
# set AP_AUTH_MODE to OPEN/SHARED/WEPAUTO/WPAPSK/WPA2PSK
AP_AUTH_MODE=`awk '{if ($1=="AP_AUTH_MODE") {print $2}}' $NETCONFIG_FILE`
# set AP_ENCRYPT_TYPE to NONE/WEP/TKIP/AES
AP_ENCRYPT_TYPE=`awk '{if ($1=="AP_ENCRYPT_TYPE") {print $2}}' $NETCONFIG_FILE`
AP_AUTH_KEY=`awk 'BEGIN { FS=" |" } {if ($1=="AP_AUTH_KEY") {print $2}}' $NETCONFIG_FILE`
# only usful when STA_ENABLE is not YES
AP_CHANNEL=`awk '{if ($1=="AP_CHANNEL") {print $2}}' $NETCONFIG_FILE`

# set ENABLE to YES/NO
BRIDGE_ENABLE=`awk '{if ($1=="BRIDGE_ENABLE") {print $2}}' $NETCONFIG_FILE`

WPA_CTRL=/var/run/wpa_supplicant
STA_IF=wlan0
STA_WPA=$WIFI_PATH/wpa_supplicant
STA_CLI=$WIFI_PATH/wpa_cli
STA_CONF=/var/run/wpa_supplicant.conf

HOSTAPD_CTRL=/var/run/hostapd
AP_IF=wlan1
AP_CMD=$WIFI_PATH/hostapd
AP_CONF=/var/run/hostapd.conf
DHCP_CONF=/var/run/dnsmasq.conf

BR_CMD=$WIFI_PATH/brctl
BR_IF=br0

killall udhcpc
killall wpa_supplicant
killall ping

if [ ! -f /var/run/wpa_supplicant ]; then
	#cp $WIFI_PATH/wpa_supplicant /var/run/wpa_supplicant
fi

if [ ! -f /var/run/wpa_supplicant.conf ]; then
	#cp $WIFI_PATH/wpa_supplicant.conf /var/run/wpa_supplicant.conf
fi

if [ ! -f /var/run/hostapd.conf ]; then
	#cp $WIFI_PATH/hostapd.conf /var/run/hostapd.conf
fi

if [ ! -f /var/run/dnsmasq.conf ]; then
	#cp $WIFI_PATH/dnsmasq.conf /var/run/dnsmasq.conf
fi

rmmod $WIFI_PATH/$STA_CHIPSET/8188eu.ko
sync
sleep 3
if [ $STA_ENABLE != "YES" ] && [ $AP_ENABLE != "YES" ]; then
	echo "there is no STA or AP device enabled!!"
	exit
fi

if [ $BRIDGE_ENABLE = "YES" ]; then
	if [ $STA_ENABLE != "YES" ] || [ $AP_ENABLE != "YES" ]; then
		echo "Both of STA_ENABLE=YES and AP_ENABLE=YES are necessary by BRIDGE_ENABLE=YES!!"
		exit
	fi
fi

ifconfig lo up
if [ $STA_CHIPSET = "RTL8188" ]; then
	echo "insert 8188eu.ko"
	if [ -f $WIFI_PATH/$STA_CHIPSET/8188eu.ko ]; then
		if [ "`lsmod | grep wlan`" = "" ]; then
			insmod $WIFI_PATH/$STA_CHIPSET/8188eu.ko
		else
			echo "module is exist"
		fi
	else
		echo "cannot find file $WIFI_PATH/$STA_CHIPSET/8188eu.ko"
	fi
elif [ $STA_CHIPSET = "RTL8189" ]; then
	echo "insert 8189es.ko"
	if [ -f $WIFI_PATH/$STA_CHIPSET/8189es.ko ]; then
		if [ "`lsmod | grep wlan`" = "" ]; then
			insmod $WIFI_PATH/$STA_CHIPSET/8189es.ko
		else
			echo "module is exist"
		fi
	else
		echo "cannot find file $STA_CHIPSET/8189es.ko"
	fi
elif [ $STA_CHIPSET = "RTL8821" ]; then
	echo "insert 8821as.ko"
	if [ -f $WIFI_PATH/$STA_CHIPSET/8821as.ko ]; then
		if [ "`lsmod | grep wlan`" = "" ]; then
			insmod $WIFI_PATH/$STA_CHIPSET/8821as.ko
		else
			echo "module is exist"
		fi
	else
		echo "cannot find file $STA_CHIPSET/8821as.ko"
	fi
fi

sleep 3
if [ $STA_ENABLE = "YES" ]; then
	#echo "Connect WIFI, SSID $STA_SSID Please Wait..." >> /dev/tty0
	ifconfig $STA_IF up
	echo "ctrl_interface=$WPA_CTRL"	>  $STA_CONF
	echo "ctrl_interface_group=0"	>> $STA_CONF
	echo "update_config=1"		>> $STA_CONF

	if [ $STA_AUTH_MODE != "WPSPBC" ] && [ $STA_AUTH_MODE != "WPSPIN" ]; then
		echo "network={"		>> $STA_CONF
		echo -e "\tssid=\"$STA_SSID\""	>> $STA_CONF

		if [ $STA_AUTH_MODE = "WPAPSK" ] || [ $STA_AUTH_MODE = "WPA2PSK" ]; then
			echo -e "\tkey_mgmt=WPA-PSK"	>> $STA_CONF
			if [ $STA_AUTH_MODE = "WPAPSK" ]; then
				echo -e "\tproto=WPA"	>> $STA_CONF
			else
				echo -e "\tproto=WPA2"	>> $STA_CONF
			fi
			if [ $STA_ENCRYPT_TYPE = "AES" ]; then
				echo -e "\tpairwise=CCMP"	>> $STA_CONF
			elif [ $STA_ENCRYPT_TYPE = "TKIP" ]; then
				echo -e "\tpairwise=TKIP"	>> $STA_CONF
			else
				"STA_ENCRYPT_TYPE \"$STA_ENCRYPT_TYPE\" does not support !!"
			fi
			echo -e "\tpsk=\"$STA_AUTH_KEY\""	>> $STA_CONF
		else
			echo -e "\tkey_mgmt=NONE"		>> $STA_CONF
			if [ $STA_ENCRYPT_TYPE = "WEP" ]; then
				echo -e "\tauth_alg=SHARED"		>> $STA_CONF
				echo -e "\twep_key0=$STA_AUTH_KEY"	>> $STA_CONF
				echo -e "\twep_tx_keyidx=0"		>> $STA_CONF
			fi
		fi

		echo "}"	>> $STA_CONF
	fi
	sync

	if [ $BRIDGE_ENABLE = "YES" ]; then
		echo "$BR_CMD addbr $BR_IF"
		$BR_CMD addbr $BR_IF
		ifconfig $BR_IF up
		echo "$BR_CMD stp $BR_IF off"
		$BR_CMD stp $BR_IF off
		echo "$BR_CMD setfd $BR_IF 0"
		$BR_CMD setfd $BR_IF 0
		echo "$STA_WPA -i $STA_IF -D wext -c $STA_CONF -b $BR_IF -B &"
		$STA_WPA -i $STA_IF -D wext -c $STA_CONF -b $BR_IF -B &
	else
		echo "$STA_WPA -i $STA_IF -D wext -c $STA_CONF &"
		$STA_WPA -i $STA_IF -D wext -c $STA_CONF &
	fi
	sleep 2

	if [ $STA_AUTH_MODE = "WPSPBC" ]; then
		echo "$STA_CLI -i $STA_IF -p $WPA_CTRL wps_pbc"
		$STA_CLI -i $STA_IF -p $WPA_CTRL wps_pbc
	elif [ $STA_AUTH_MODE = "WPSPIN" ]; then
		echo "$STA_CLI -i $STA_IF -p $WPA_CTRL wps_pin any"
		$STA_CLI -i $STA_IF -p $WPA_CTRL wps_pin any
	elif [ $STA_AUTH_MODE = "WPSREG" ]; then
		sleep 2
		#pin=`$STA_CLI -i $STA_IF -p $WPA_CTRL scan_result | awk '{if ($5=="'$STA_SSID'") {printf $1}}'`
		pin=`$STA_CLI -i $STA_IF -p $WPA_CTRL scan_result | awk '{if (NF>5) {for(i=6;i<=NF;i++) $5=$5" "$i} if ($5=="'"$STA_SSID"'") {printf $1}}'`
		#echo "pin=\"$pin\""
		echo "$STA_CLI -i $STA_IF -p $WPA_CTRL wps_reg $pin $STA_AUTH_KEY"
		$STA_CLI -i $STA_IF -p $WPA_CTRL wps_reg $pin $STA_AUTH_KEY
	else
		counter=1
		while [ 1 ]; do
			StaStatus=`$STA_CLI -i $STA_IF -p $WPA_CTRL status | awk -F= '{if ($1=="wpa_state") {print $2}}'`
			echo "Wait.. ($counter/30), Status=$StaStatus" 
			if [ $StaStatus = "COMPLETED" ]; then
			#if [ $StaStatus = "ASSOCIATING" ]; then
				STA_CONFIG_FAIL="ok"
				echo "STA connect to AP ok ^_^"
				AP_ENABLE="NO"
				break
			elif [ $StaStatus = "INACTIVE" ]; then
				echo "STA connect to AP failed!!"
				#sed "1c STA_ENABLE NO" /mnt/spiflash/network_config -i
				killall wpa_supplicant
				STA_CONFIG_FAIL="no"
				AP_ENABLE="NO"
				#STA_ENABLE="no"
				break
			fi
			counter=`expr $counter + 1`
			if [ $counter -gt 30 ]; then
				echo "STA connect to AP timeout!!!"
				killall wpa_supplicant
				STA_CONFIG_FAIL="no"
				AP_ENABLE="NO"
				#STA_ENABLE="no"
				break
			fi
			sleep 1
		done
	fi

	if [ $BRIDGE_ENABLE = "YES" ]; then
		echo "$BR_CMD addif $BR_IF $STA_IF"
		$BR_CMD addif $BR_IF $STA_IF
		if [ $STA_BOOTPROTO = "DHCP" ]; then
			echo "udhcpc -i $BR_IF"
			udhcpc -i $BR_IF -T 1
		else
			echo "ifconfig $BR_IF $STA_IPADDR netmask 255.255.255.0"
			ifconfig $BR_IF $STA_IPADDR netmask 255.255.255.0

			if [ -n "$STA_GATEWAY" ]; then
				echo "route add default gw $STA_GATEWAY $BR_IF"
				route add default gw $STA_GATEWAY $BR_IF
			fi
		fi
	else
		if [ $STA_CONFIG_FAIL = "ok" ]; then
			echo "set wifi ip address"
			if [ $STA_BOOTPROTO = "DHCP" ]; then
				echo "udhcpc -i $STA_IF"
				#udhcpc -i $STA_IF -T 1
				udhcpc -i $STA_IF -q -T 16 -n 
			else
				echo "ifconfig $STA_IF $STA_IPADDR netmask 255.255.255.0"
				ifconfig $STA_IF $STA_IPADDR netmask 255.255.255.0

				if [ -n "$STA_GATEWAY" ]; then
					echo "route add default gw $STA_GATEWAY $STA_IF"
					route add default gw $STA_GATEWAY $STA_IF
				fi
			fi
		fi
	fi
fi

if [ $AP_ENABLE = "YES" ]; then
	#echo "Config WIFI, SSID $AP_SSID Please Wait..." >> /dev/tty0
	if [ $STA_ENABLE = "YES" ]; then
		if [ $STA_BOOTPROTO = "STATIC" ]; then
			sleep 3
		fi
		#freq=`$STA_CLI -i $STA_IF -p $WPA_CTRL scan_result | awk '{if ($5=="'$STA_SSID'") {printf $2}}'`
		freq=`$STA_CLI -i $STA_IF -p $WPA_CTRL scan_result | awk '{if (NF>5) {for(i=6;i<=NF;i++) $5=$5" "$i} if ($5=="'"$STA_SSID"'") {printf $2}}'`
		echo "freq=$freq"
		if [ $freq -lt "5000" ]; then
			freq_off=`expr $freq - 2407`
		else
			freq_off=`expr $freq - 5000`
		fi
		#echo "freq_off=$freq_off"
		ch=`expr $freq_off / 5`
	else
		ch=$AP_CHANNEL
	fi
	echo "ch=$ch"
	
	cat hostapd.conf.default		>  $AP_CONF
	if [ $ch -gt "14" ]; then
		echo "hw_mode=a"		>> $AP_CONF
	else
		echo "hw_mode=g"		>> $AP_CONF
	fi
	if [ $STA_CHIPSET = "RTL8821" ]; then
		echo "ieee80211n=1"		>> $AP_CONF
	fi
	echo "ssid=$AP_SSID"			>> $AP_CONF
	echo "interface=$AP_IF"			>> $AP_CONF
	echo "channel=$ch"			>> $AP_CONF

	if [ $AP_AUTH_MODE = "WPA2PSK" ] || [ $AP_AUTH_MODE = "WPAPSK" ]; then
		echo "auth_algs=3"		>> $AP_CONF
		if [ $AP_AUTH_MODE = "WPA2PSK" ]; then
			echo "wpa=2"		>> $AP_CONF
		else
			echo "wpa=1"		>> $AP_CONF
		fi
		echo "wpa_key_mgmt=WPA-PSK"	>> $AP_CONF
		if [ $AP_ENCRYPT_TYPE = "AES" ]; then
			echo "ieee80211n=1"		>> $AP_CONF
			echo "wpa_pairwise=CCMP"	>> $AP_CONF
		elif [ $AP_ENCRYPT_TYPE = "AES" ]; then
	                echo "wpa_pairwise=TKIP" 	>> $AP_CONF
		else
		fi
		echo "wpa_passphrase=$AP_AUTH_KEY"	>> $AP_CONF

	elif [ $AP_AUTH_MODE = "WEPAUTO" ]; then
		echo "auth_algs=3"			>> $AP_CONF
		echo "wep_default_key=0"		>> $AP_CONF
		echo "wep_key0=\"$AP_AUTH_KEY\""	>> $AP_CONF
		echo "wpa=0"				>> $AP_CONF
	elif [ $AP_AUTH_MODE = "OPEN" ] || [ $AP_AUTH_MODE = "SHARED" ]; then
		if [ $AP_AUTH_MODE = "SHARED" ]; then
			echo "auth_algs=2"		>> $AP_CONF
		else
			echo "auth_algs=1"		>> $AP_CONF
		fi
		if [ "$AP_ENCRYPT_TYPE" != "NONE" ]; then
			echo "wep_default_key=0"		>> $AP_CONF
			echo "wep_key0=\"$AP_AUTH_KEY\""	>> $AP_CONF
		fi
		echo "wpa=0"					>> $AP_CONF
	else
		"AP_AUTH_MODE \"$AP_AUTH_MODE\" does not support !!"
	fi

	if [ $BRIDGE_ENABLE = "YES" ]; then
		echo "bridge=$BR_IF"			>> $AP_CONF
		$AP_CMD $AP_CONF -B &
		echo "$BR_CMD addif $BR_IF $AP_IF"
		$BR_CMD addif $BR_IF $AP_IF
	else
		$AP_CMD $AP_CONF &
	fi

	echo "ifconfig $AP_IF $AP_IPADDR netmask 255.255.255.0"
	ifconfig $AP_IF $AP_IPADDR netmask 255.255.255.0

#	if [ -n "$AP_GATEWAY" ]; then
#		echo "route add default gw $AP_GATEWAY $AP_IF"
#		route add default gw $AP_GATEWAY $AP_IF
#	fi

	SUBNET=`echo $AP_IPADDR | awk 'BEGIN {FS="."} { print $1"."$2"."$3}'`
	cat dnsmasq.conf.default						>  $DHCP_CONF
	echo "interface=$AP_IF"							>> $DHCP_CONF
	echo "dhcp-option=lan,3"						>> $DHCP_CONF
	echo "dhcp-option=lan,6"						>> $DHCP_CONF
	echo "dhcp-option=vendor:MSFT,2,1i"					>> $DHCP_CONF
	echo "dhcp-range=lan,$SUBNET.100,$SUBNET.199,255.255.255.0,14400m"	>> $DHCP_CONF
	echo "./dnsmasq --conf-file=$DHCP_CONF --pid-file=/tmp/dnsmasq.pid --user=root --group=root"
	./dnsmasq --conf-file=$DHCP_CONF --pid-file=/tmp/dnsmasq.pid --user=root --group=root &
fi

